0x01
反调试主要分为两种,第一种阻止调试器附加,第二种是检测是否有调试器存在
0x02
第一种方法:
0x01 ptrace
ptrace是系统用来对运行中的进程进行调试和跟踪的工具,通过ptrace,可以对另一个进程实现调试跟踪。但是里面提供了一个非常有用的参数,就是PT_DENY_ATTACH,const值是31,这个参数用户告诉系统阻止调试器附加。
在main.m里面加入以下代码:
1 | #import <UIKit/UIKit.h> |
在上面的代码中,本来是直接调用上面被注释的那一行代码就可以了,不过由于不是公开的函数所以没法直接调用。所以我们通过dlopen的方式,当path 参数为0是,他会自动查找 $LD_LIBRARY_PATH,$DYLD_LIBRARY_PATH, $DYLD_FALLBACK_LIBRARY_PATH 和 当前工作目录中的动态链接库,通过句柄找到对应的ptarce对应的地址,然后传入PT_DENY_ATTACH。
0x02 syscall
另外一种方式可以使用syscall的方式来调用ptrace,syscall是系统提供的一个系统调用函数,因为上面的调用方式会容易被反反调试,通过NSFindSymbol找到_ptrace然后hook对应的函数,所以可以最好是通过syscall来反调试
在Kernel Syscalls里面找到ptrace对应的const。
1 | $ joker -u ~/Documents/projects/iOS.6.0.iPod4.kernel |
注意一下代码中的26就是ptrace的const。
综上所述:调用syscall(26,31,0,0,0)就可以达到反调试的目的。
0x03 sysctl
可以通过sysctl查看内核进程状态标志位,如果一个进程在调试状态,会有一个标志位(info.kp_proc.p_flag)来标识当前是否正在调试。
代码如下:
1 | BOOL existDebugger(){ |
可以定时执行以上代码,当检测到程序正在被调试,可以调用exit(0)来让程序奔溃或者做其他的操作
0x04
syscall可以通过软中断实现从用户态切换到系统内核态的转换,同时可以通过arm 汇编实现以上功能。通过asm volatile内联汇编,实际上也是调用了ptrace。
代码如下:
1 | #ifdef __arm__ |